﻿using Microsoft.VisualBasic.ApplicationServices;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SudokuGame.Sudoku
{
    public class SudokuCenter : IDisposable
    {
        public bool IsStart { get; set; } = false;
        private int _width;
        private int _height;
        public const int CELLSNUMBER = 9;
        public const int CELLSNUMBER2 = 20;
        private int _cellSize;
        private int _rowSize;
        public int CellSize=> _cellSize;
        public int RowSize => _rowSize;
        public int Height => _height;
        public int Width => _width;
        public int Padding => CELLSNUMBER2;
        private Bitmap _bitmap;
        public Bitmap GetBitmap
        {
            get=>(Bitmap)_bitmap?.Clone();
            private set => _bitmap = value;
        }
        public SudokuCell[,] Suduku { get;private set; }
        public SudokuCell[,] PlayerSuduku { get; private set; }
        /// <summary>
        /// 生成棋盘图
        /// </summary>
        /// <param name="w"></param>
        /// <param name="h"></param>
        public void InitCheckerBoard(int w, int h)
        {
            w -= (CELLSNUMBER2 * 2 + 1);
            h -= (CELLSNUMBER2 * 2 + 1);
            _width = w;
            _height = h;
            _cellSize = _width / CELLSNUMBER;
            _rowSize = _height / CELLSNUMBER;
            Bitmap bitmap = new Bitmap(_width + CELLSNUMBER2, _height + CELLSNUMBER2);
            using (var g = Graphics.FromImage(bitmap))
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                //g.Clear(Color.Gray);
                DrawCheckerBoard(g);
            }
            _bitmap?.Dispose();
            GetBitmap = bitmap;
        }
        public SudokuCell[,] GenerateSudoku(DifficultyLevel difficulty)
        {
            SudokuGenerator sudokuGenerator = new SudokuGenerator();
            Suduku = sudokuGenerator.GenerateSudoku(difficulty);
            PlayerSuduku = new SudokuCell[Suduku.GetLength(0), Suduku.GetLength(1)];
            Array.Copy(Suduku, PlayerSuduku, Suduku.Length);
            return Suduku;
        }
        public Color SudukuColor { get; set; }= Color.Black;
        public Color SolutionColor { get; set; } = Color.Red;
        public Color TransparentColor { get; } = Color.Transparent;
        public Font Font { get; set; }= new Font("Arial", 20, FontStyle.Bold);

        public Bitmap DrawSolution(SudokuCell[,] board)
        {
            using SolidBrush brush = new SolidBrush(SolutionColor);
            using SolidBrush brush2 = new SolidBrush(SudukuColor);
            var bm = GetBitmap;
            using var g = Graphics.FromImage(bm);
            for (int row = 0; row < CELLSNUMBER; row++)
            {
                for (int col = 0; col < CELLSNUMBER; col++)
                {
                   
                    int number = Suduku[row, col].Number;
                    if (number != 0)
                    {
                        DrawString(g, row, col, number.ToString(), brush2);
                    }
                    else
                    {
                        number = board[row, col].Number;
                        DrawString(g, row, col, number.ToString(), brush);
                    }
                }
            }
            return bm;
        }
        public void DrawSudoku(Graphics g, SudokuCell[,] board)
        {
            using SolidBrush brush = new SolidBrush(SudukuColor);


            for (int row = 0; row < CELLSNUMBER; row++)
            {
                for (int col = 0; col < CELLSNUMBER; col++)
                {
                   int num= board[row, col].Number;
                    if((num != 0))
                    {
                        DrawString(g,row,col,num.ToString(), brush);
                    }
                }
            }
        }
        public void DrawString(Graphics g,int row,int col,string number, SolidBrush brush)
        {
            int x = CELLSNUMBER2 + col * _cellSize + _cellSize / 2 - 8;
            int y = CELLSNUMBER2 + row * _rowSize + _rowSize / 2 - 10;
            g.DrawString(number, Font, brush, new Point(x, y));
           
        }
        public Rectangle DrawTransparent(Graphics g, int row, int col)
        {
            int off = 5;
            int off2 = 7;
            int x = CELLSNUMBER2 + col * _cellSize + off;
            int y = CELLSNUMBER2 + row * _rowSize+ off;
            using (SolidBrush brush = new SolidBrush(Color.White)) // 使用透明色进行擦除
            {
                var rec = new Rectangle(x, y, CellSize - off2, RowSize - off2);
                g.FillRectangle(brush, rec);
                return rec;
            }
        }
        public bool IsSolutionCorrect(SudokuCell[,] board, SudokuCell[,] solution)
        {
            for (int row = 0; row < CELLSNUMBER; row++)
            {
                for (int col = 0; col < CELLSNUMBER; col++)
                {
                    if (board[row, col].Number != solution[row, col].Number)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        public bool IsValidMove(SudokuCell[,] board, int row, int col, int num)
        {
            // 检查行是否合法
            for (int i = 0; i < CELLSNUMBER; i++)
            {
                if (board[i, col].Number == num)
                {
                    return false;
                }
            }

            // 检查列是否合法
            for (int i = 0; i < CELLSNUMBER; i++)
            {
                if (board[row, i].Number == num)
                {
                    return false;
                }
            }

            // 检查子网格是否合法
            int subgridRow = (row / 3) * 3;
            int subgridCol = (col / 3) * 3;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (board[subgridRow + i, subgridCol + j].Number == num)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        private void DrawCheckerBoard(Graphics g)
        {
            using Pen pen = new Pen(Color.Black, 1);
            using Pen pen2 = new Pen(Color.Black, 2);
            using Font font = new Font("Arial", 10, FontStyle.Regular);
            using SolidBrush brush = new SolidBrush(Color.Black);

            for (int i = 0; i < CELLSNUMBER + 1; i++)
            {
                if (i == 0 || i % 3 == 0)
                {
                    g.DrawLine(pen2, new Point(CELLSNUMBER2, CELLSNUMBER2 + i * _rowSize), new Point(CELLSNUMBER2 + _cellSize * CELLSNUMBER, CELLSNUMBER2 + i * _rowSize));
                    g.DrawLine(pen2, new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + 0), new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + _rowSize * CELLSNUMBER));
                }
                else
                {
                    g.DrawLine(pen, new Point(CELLSNUMBER2, CELLSNUMBER2 + i * _rowSize), new Point(CELLSNUMBER2 + _cellSize * CELLSNUMBER, CELLSNUMBER2 + i * _rowSize));
                    g.DrawLine(pen, new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + 0), new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + _rowSize * CELLSNUMBER));
                }


                int x = CELLSNUMBER2 + i * _cellSize + _cellSize / 2 - 5;
                int y = 0;
                g.DrawString((i + 1).ToString(), font, brush, new Point(x, y));

                x = 0;
                y = CELLSNUMBER2 + i * _rowSize + _rowSize / 2 - 5;
                g.DrawString((i + 1).ToString(), font, brush, new Point(x, y));
            }
        }

        public void Dispose()
        {
            _bitmap?.Dispose();
        }
    }
}
